import { ref, type App } from "vue"

// 定义通知图片项接口
export interface NotifyImageItem {
    label: string;
    name: string;
    value: number;
}

// 定义字典项接口
export interface DictItem {
    [key: string]: any;
    value?: string | number;
    label?: string;
}

// 定义字典映射接口
export interface DictMappingType {
    [key: string]: Record<string | number, DictItem>;
}

// 定义字典队列缓存接口
export interface DictQueueCacheType {
    [key: string]: Promise<any>;
}

// 定义格式化字典选项接口
export interface FormatDictOptions {
    type: string;
    key?: string;
}
const Dict: Record<string, any> = {
    type: [{ label: 'label1', value: 1 }, { label: 'label2', value: 2 }]
};
const DictMapping: DictMappingType = {};
const DictQueueCache: DictQueueCacheType = {};

const DictQueueEvent = async function (type: string): Promise<any> {
    return new Promise((resolve, reject) => {
        if (Dict[type]) {
            resolve(Dict[type]);
        } else {
            reject(new Error('字典类型不存在'));
        }
    })
}

async function GetDict(type: string): Promise<any> {
    if (type && Dict[type]) {
        return JSON.parse(JSON.stringify(Dict[type]));
    } else if (type && !Dict[type]) {
        // @ts-ignore
        if (DictQueueCache[type]) {
            return DictQueueCache[type];
        } else {
            const _event = DictQueueEvent(type);
            DictQueueCache[type] = _event;
            try {
                const res = await _event;
                Dict[type] = res;
                delete DictQueueCache[type];
                return res;
            } catch (error) {
                delete DictQueueCache[type];
                throw error;
            }
        }
    }
    return undefined;
}
async function FormatDictToMapping(options: FormatDictOptions): Promise<Record<string | number, DictItem>> {
    const type = options.type;
    const key = options.key || 'value';
    try {
        const res = await GetDict(type);
        if (!res) return {};

        const _data: Record<string | number, DictItem> = {};
        res.forEach((item: DictItem) => {
            _data[item[key]] = item;
        });
        return _data;
    } catch (error) {
        console.error('格式化失败=>', type, error);
        return {};
    }
}

function FilterNull(value: any): string {
    if (value === null || value === undefined || value === 'null' || value === 'undefined') {
        return '';
    } else {
        return String(value);
    }
}

const GetValue = async function (
    type: string,
    value: string | number,
    valueKey: string = 'value',
    showKey: string = 'label'
): Promise<string> {
    let _dict = DictMapping[`${type}_${valueKey}_${showKey}`];
    if (!_dict) {
        _dict = DictMapping[`${type}_${valueKey}_${showKey}`] = await FormatDictToMapping({ type, key: valueKey });
    }
    if (_dict[value] && _dict[value][showKey]) {
        return String(_dict[value][showKey]);
    } else {
        return FilterNull(value);
    }
};


const dictEvent = async function (
    el: HTMLElement,
    binding: any,
): Promise<void> {
    const type = binding.arg;
    const options = binding.value;
    let value: string | number;
    let valueKey: string;
    let showKey: string;

    if (Array.isArray(options)) {
        value = options[0];
        valueKey = options[1] || 'value';
        showKey = options[2] || 'label';
    } else {
        value = options;
        valueKey = 'value';
        showKey = 'label';
    }

    let _dict = DictMapping[`${type}_${valueKey}_${showKey}`];
    if (!_dict) {
        _dict = DictMapping[`${type}_${valueKey}_${showKey}`] = await FormatDictToMapping({ type, key: valueKey });
    }

    if (_dict[value] && _dict[value][showKey]) {
        el.innerHTML = String(_dict[value][showKey]);
    } else {
        el.innerHTML = FilterNull(value);
    }
};

export const useDictList = function (type: string) {
    const list = ref([]);
    GetDict(type).then((res) => {
        list.value = res;
    })
    return list;
}

export const useDict = function (dict: string, val: any, valueKey: string = 'value', showKey: string = 'label') {
    const value = ref(val);
    GetValue(dict, val, valueKey, showKey).then((res) => {
        value.value = res;
    })
    return value
}



export default {
    install(app: App) {
        app.directive('dict', dictEvent);
    }
}
